package com.cj.flowabletest.controller;
import java.util.Date;

import com.cj.flowabletest.model.AskForLeaveVo;
import com.cj.flowabletest.model.RespBean;
import com.cj.flowabletest.model.TaskVo;
import com.cj.flowabletest.model.User;
import com.cj.flowabletest.service.AskForLeaveService;

import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ActivityInstance;
import org.flowable.image.impl.DefaultProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author cc
 * @date 2025-03-03 16:11
 **/
@RestController
public class AskForLeaveController {


    @Autowired
    AskForLeaveService askForLeaveService;

   @PostMapping("/ask_for_leave")
    public RespBean askForLeave(@RequestBody AskForLeaveVo askForLeaveVo){
       return askForLeaveService.askForLeave(askForLeaveVo);
   }


   @GetMapping("/unapprove")
   public List<AskForLeaveVo> getUnapproveProcess(){
       List<AskForLeaveVo> list =   askForLeaveService.getUnapproveProcess();

       return list;
   }
   @Autowired
    RepositoryService repositoryService;

   @Autowired
    RuntimeService runtimeService;

   @GetMapping("/image/{processId}")
   public void processImage(@PathVariable String processId, HttpServletResponse resp) throws IOException {

       // 流程定义
       ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionKey("askforleave_demo").latestVersion().singleResult();

       // 画图的对象
       BpmnModel bpmnModel = repositoryService.getBpmnModel(pd.getId());

       // 查询流程实例
       DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();

       // 哪些活动是高亮的
       List<String> highLightActivities = new ArrayList<>();
       // 哪些线条是高亮的
       List<String> highLightFlows = new ArrayList<>();


       List<ActivityInstance> instances = runtimeService.createActivityInstanceQuery().processInstanceId(processId).list();
       for (ActivityInstance instance : instances) {
           if (instance.getActivityType().equals("sequenceFlow")){
               highLightFlows.add(instance.getActivityId());
           }else{
               highLightActivities.add(instance.getActivityId());
           }
       }

       InputStream inputStream = generator.generateDiagram(bpmnModel, "png", highLightActivities, highLightFlows, 1.0, true);

       resp.setContentType(MediaType.IMAGE_PNG_VALUE);
       FileCopyUtils.copy(inputStream,resp.getOutputStream());
   }

   @Autowired
    TaskService taskService;


   @GetMapping("/current_user_task")
   public List<TaskVo> getCurrentUserAllTask(){
       User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
       List<Task> taskList = taskService.createTaskQuery().taskAssignee(user.getUsername()).list();

       List<TaskVo> list = new ArrayList<>();
       for (Task task : taskList) {
           TaskVo taskVo = new TaskVo();



           Integer days = (Integer) taskService.getVariable(task.getId(), "days");
           String reason = (String) taskService.getVariable(task.getId(), "reason");
           Date startTime = (Date) taskService.getVariable(task.getId(), "startTime");
           Date endTime = (Date) taskService.getVariable(task.getId(), "endTime");
           String approveUser = (String) taskService.getVariable(task.getId(), "approveUser");
           String applicant = (String) taskService.getVariable(task.getId(), "applicant");

           taskVo.setDays(days);
           taskVo.setReason(reason);
           taskVo.setStartTime(startTime);
           taskVo.setEndTime(endTime);
           taskVo.setApproveUser(approveUser);
           taskVo.setTaskId(task.getId());
           taskVo.setApproval(null);
           taskVo.setApplicant(applicant);


           list.add(taskVo);
       }

       return list;

   }


   @PostMapping("/approval")
   public void approve(@RequestBody TaskVo taskVo){
       HashMap<String, Object> map = new HashMap<>();
       map.put("approval",taskVo.getApproval());

       // 审批
       taskService.complete(taskVo.getTaskId(),map);
   }

   @Autowired
    HistoryService historyService;
   @GetMapping("/history")
   public  List<AskForLeaveVo> getHistoryProcess(){
       User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();


       // 查询已经完成的流程
       List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().startedBy(user.getUsername()).finished().list();

       List<AskForLeaveVo> askForLeaveVOs = new ArrayList<>();
       for (HistoricProcessInstance hpi : list) {
           AskForLeaveVo askForLeaveVo = new AskForLeaveVo();
           List<HistoricVariableInstance> historyVariableList = historyService.createHistoricVariableInstanceQuery().processInstanceId(hpi.getId()).list();
           for (HistoricVariableInstance historicVariableInstance : historyVariableList) {
               String variableName = historicVariableInstance.getVariableName();
               Object value = historicVariableInstance.getValue();
               askForLeaveVo.setProcessId(hpi.getId());
               if ("days".equals(variableName)){
                   askForLeaveVo.setDays((Integer) value);

               }else if ("approveUser".equals(variableName)){
                    askForLeaveVo.setApproveUser((String) value);
               }else if ("reason".equals(variableName)){
                   askForLeaveVo.setReason((String) value);
               }else if ("startTime".equals(variableName)){
                   askForLeaveVo.setStartTime((Date) value);
               }else if ("endTime".equals(variableName)){
                   askForLeaveVo.setEndTime((Date) value);
               }else if ("approval".equals(variableName)){
                   askForLeaveVo.setApproval(((Boolean) value));
               }
           }


           askForLeaveVOs.add(askForLeaveVo);
       }

       return askForLeaveVOs;
   }


    @GetMapping("/history/image/{processId}")
    public void processImageHistory(@PathVariable String processId, HttpServletResponse resp) throws IOException {

        // 流程定义
        ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionKey("askforleave_demo").latestVersion().singleResult();

        // 画图的对象
        BpmnModel bpmnModel = repositoryService.getBpmnModel(pd.getId());

        // 查询流程实例
        DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();

        // 哪些活动是高亮的
        List<String> highLightActivities = new ArrayList<>();
        // 哪些线条是高亮的
        List<String> highLightFlows = new ArrayList<>();


        // 完成的可以查到，没有完成的也能查到
        List<HistoricActivityInstance> instances = historyService.createHistoricActivityInstanceQuery().processInstanceId(processId).list();
        for (HistoricActivityInstance instance : instances) {
            if (instance.getActivityType().equals("sequenceFlow")){
                highLightFlows.add(instance.getActivityId());
            }else{
                highLightActivities.add(instance.getActivityId());
            }
        }

        InputStream inputStream = generator.generateDiagram(bpmnModel, "png", highLightActivities, highLightFlows, 1.0, true);

        resp.setContentType(MediaType.IMAGE_PNG_VALUE);
        FileCopyUtils.copy(inputStream,resp.getOutputStream());
    }
}
